home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
GRAPHICS
/
GIF2RPC.SPK
/
source
/
16bpp_66bit
/
c
/
sierra3
< prev
next >
Wrap
Text File
|
1995-10-16
|
5KB
|
124 lines
/* sierra3.c
* AUTHOR: Cy Booker, cy@cheepnis.demon.co.uk
* LICENSE: FreeWare, Copyright (c) 1995 Cy Booker
*
* filter: * 5 3
* 2 4 5 4 2
* 2 3 2 (1/32)
*/
#include "internal.h"
#include <assert.h>
#include <string.h> /* memset() */
#include <stdlib.h> /* calloc() */
#include "OS:hourglass.h"
#include "OS:macros.h"
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
extern bool process_gif_16bpp_sierra3_66bit(
const process_gif *p) {
byte *rove;
int width, height;
int x, y;
const os_colour *palette;
int line_length;
int *buffer, *this_row, *next_row, *botm_row;
int buffer_width;
int r, g, b;
int or, og, ob;
int t;
int er, eg, eb;
int rr, rg, rb; /* remainders */
assert(p);
assert(p->pixel_width > 0);
assert(p->pixel_height > 0);
assert(p->in_palette.colours);
/*
* sierra3 requires storing error info for two pixels to right and two pixels to left
* so we will just allocate two extra columns for each row and not do any edge checks
* each entry is stored as {r*SCALE, g*SCALE, b*SCALE}
*/
buffer_width = (2 + p->pixel_width + 2) * 3;
buffer = calloc(1, sizeof(*buffer) * (buffer_width * 3));
if (!buffer) {
/*
* oh dear
*/
return TRUE;
}
initialise_scaling_tables();
/*
* not we pre-load values from the process_gif array
* because it considerably helps the compiler produce better code
*/
rove = p->buffer;
width = p->pixel_width;
height = p->pixel_height;
palette = p->in_palette.colours;
line_length = p->line_length;
for (y= height; (y > 0); y--) {
if ((y & 7) == 0) {
xhourglass_percentage((y * 100) / height);
}
this_row = buffer + (buffer_width * ((y + 3) % 3)) + 2*3;
next_row = buffer + (buffer_width * ((y + 2) % 3)) + 2*3;
botm_row = buffer + (buffer_width * ((y + 1) % 3)) + 2*3;
/* bottom row has no errors */
memset(botm_row, 0, sizeof(*botm_row) * (buffer_width - 2*3));
/*
* note that just because we are actually scanning/outputting right to left
* doesn't matter as far as the filter is concerned
* although it might help if we could ``snake''
*/
for (x= width - 1; (x >= 0); x--) {
INPUT;
r += *this_row++; /* add in errors from all rows */
g += *this_row++;
b += *this_row++;
PROCESS;
r -= or; g -= og; b-= ob; /* error */
er = (r * 5) / 32; eg = (g * 5) / 32; eb = (b * 5) / 32;
this_row[ 0] += er; this_row[ 1] += eg; this_row[ 2] += eb; /* this[ 1] += 5/32 */
next_row[ 0] += er; next_row[ 1] += eg; next_row[ 2] += eb; /* next[ 0] += 5/32 */
rr = r - (2*er); rg = g - (2*eg); rb = b - (2*eb); /* remainder of error left */
er = (r * 4) / 32; eg = (g * 4) / 32; eb = (b * 4) / 32;
next_row[ 3] += er; next_row[ 4] += eg; next_row[ 5] += eb; /* next[ 1] += 4/32 */
next_row[-3] += er; next_row[-2] += eg; next_row[-1] += eb; /* next[-1] += 4/32 */
rr -= 2*er; rg -= 2*eg; rb -= 2*eb; /* remainder of error left */
er = (r * 3) / 32; eg = (g * 3) / 32; eb = (b * 3) / 32;
this_row[ 3] += er; this_row[ 4] += eg; this_row[ 5] += eb; /* this[ 2] += 3/32 */
botm_row[ 0] += er; botm_row[ 1] += eg; botm_row[ 2] += eb; /* botm[ 0] += 3/32 */
rr -= 2*er; rg -= 2*eg; rb -= 2*eb; /* remainder of error left */
er = (r * 2) / 32; eg = (g * 2) / 32; eb = (b * 2) / 32;
next_row[ 6] += er; next_row[ 7] += eg; next_row[ 8] += eb; /* next[ 2] += 2/32 */
next_row[-6] += er; next_row[-5] += eg; next_row[-4] += eb; /* next[-2] += 2/32 */
botm_row[-3] += er; botm_row[-2] += eg; botm_row[-1] += eb; /* botm[-1] += 2/32 */
rr -= 3*er; rg -= 3*eg; rb -= 3*eb; /* remainder of error left */
botm_row += 3; /* adjust next_row pointer */
botm_row[ 0] += rr; botm_row[ 1] += rg; botm_row[ 2] += rb; /* botm[ 1] += 2/32 */
next_row += 3; /* adjust next_row pointer */
}
rove += line_length;
}
free(buffer);
return FALSE;
}